'use client'

import React from 'react'
import { Button, Result } from 'antd'

interface ErrorBoundaryState {
    hasError: boolean
    error: Error | null
    errorInfo: React.ErrorInfo | null
}

interface ErrorBoundaryProps {
    children: React.ReactNode
    fallback?: React.ComponentType<{ error: Error; retry: () => void }>
}

export class ErrorBoundary extends React.Component<
    ErrorBoundaryProps,
    ErrorBoundaryState
> {
    constructor(props: ErrorBoundaryProps) {
        super(props)
        this.state = {
            hasError: false,
            error: null,
            errorInfo: null
        }
    }

    static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {
        return { hasError: true, error }
    }

    componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
        console.error('Application Error:', error, errorInfo)

        this.setState({
            error,
            errorInfo
        })

        // 发送错误报告到监控服务
        this.reportError(error, errorInfo)
    }

    reportError = (error: Error, errorInfo: React.ErrorInfo) => {
        // 实现错误报告逻辑
        if (process.env.NODE_ENV === 'development') {
            console.group('🚨 Error Boundary Caught Error')
            console.error('Error:', error)
            console.error('Error Info:', errorInfo)
            console.error('Component Stack:', errorInfo.componentStack)
            console.groupEnd()
        }

        // 在生产环境中，可以发送到错误监控服务
        // 例如: Sentry, LogRocket, 或自定义错误收集服务
    }

    handleRetry = () => {
        this.setState({
            hasError: false,
            error: null,
            errorInfo: null
        })
    }

    render() {
        if (this.state.hasError) {
            // 如果提供了自定义fallback组件，使用它
            if (this.props.fallback && this.state.error) {
                const FallbackComponent = this.props.fallback
                return <FallbackComponent error={this.state.error} retry={this.handleRetry} />
            }

            // 默认错误界面
            return (
                <div className="error-boundary-container min-h-screen flex items-center justify-center bg-gray-50">
                    <div className="max-w-md w-full">
                        <Result
                            status="error"
                            title="应用程序出现错误"
                            subTitle="很抱歉，应用程序遇到了意外错误。请尝试刷新页面或联系技术支持。"
                            extra={[
                                <Button
                                    type="primary"
                                    key="retry"
                                    onClick={this.handleRetry}
                                >
                                    重试
                                </Button>,
                                <Button
                                    key="refresh"
                                    onClick={() => window.location.reload()}
                                >
                                    刷新页面
                                </Button>,
                                <Button
                                    key="home"
                                    onClick={() => window.location.href = '/'}
                                >
                                    返回首页
                                </Button>
                            ]}
                        />

                        {/* 开发环境显示详细错误信息 */}
                        {process.env.NODE_ENV === 'development' && this.state.error && (
                            <details className="mt-4 p-4 bg-red-50 border border-red-200 rounded">
                                <summary className="cursor-pointer font-medium text-red-800">
                                    开发调试信息 (点击展开)
                                </summary>
                                <div className="mt-2 text-sm">
                                    <div className="mb-2">
                                        <strong>错误消息:</strong>
                                        <pre className="mt-1 text-red-700 whitespace-pre-wrap">
                                            {this.state.error.message}
                                        </pre>
                                    </div>
                                    <div className="mb-2">
                                        <strong>错误堆栈:</strong>
                                        <pre className="mt-1 text-red-600 text-xs whitespace-pre-wrap overflow-auto max-h-32">
                                            {this.state.error.stack}
                                        </pre>
                                    </div>
                                    {this.state.errorInfo && (
                                        <div>
                                            <strong>组件堆栈:</strong>
                                            <pre className="mt-1 text-red-600 text-xs whitespace-pre-wrap overflow-auto max-h-32">
                                                {this.state.errorInfo.componentStack}
                                            </pre>
                                        </div>
                                    )}
                                </div>
                            </details>
                        )}
                    </div>
                </div>
            )
        }

        return this.props.children
    }
}

// 函数式错误边界Hook (用于特定组件)
export const withErrorBoundary = <P extends object>(
    Component: React.ComponentType<P>,
    fallback?: React.ComponentType<{ error: Error; retry: () => void }>
) => {
    const WrappedComponent = (props: P) => (
        <ErrorBoundary fallback={fallback}>
            <Component {...props} />
        </ErrorBoundary>
    )

    WrappedComponent.displayName = `withErrorBoundary(${Component.displayName || Component.name})`

    return WrappedComponent
}

export default ErrorBoundary